package com.bite.order.sentinel;

import com.alibaba.csp.sentinel.datasource.FileRefreshableDataSource;
import com.alibaba.csp.sentinel.datasource.FileWritableDataSource;
import com.alibaba.csp.sentinel.datasource.WritableDataSource;
import com.alibaba.csp.sentinel.init.InitFunc;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.transport.util.WritableDataSourceRegistry;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;

import java.io.File;
import java.io.IOException;
import java.util.List;

public class FileDataSourceInit implements InitFunc {
    @Override
    public void init() throws Exception {
        String prefixPath = System.getProperty("user.home") + "/sentinel/rules/order-service";
        String flowRulePath = prefixPath + "/flow-rule.json";
        mkdirsIfNotExist(prefixPath);
        createFileIfNotExist(flowRulePath);

        // 注册⼀个可读数据源，⽤来定时读取本地的json⽂件，更新到规则缓存中
        //流控规则（其他的要分别设置
        FileRefreshableDataSource<List<FlowRule>> ds = new FileRefreshableDataSource<>(flowRulePath,
                source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
        }));

        // 将可读数据源注册⾄FlowRuleManager
        // 这样当规则⽂件发⽣变化时，就会更新规则到内存
        FlowRuleManager.register2Property(ds.getProperty());
        WritableDataSource<List<FlowRule>> flowRuleWDS = new
                FileWritableDataSource<>(
                flowRulePath,
                this::encodeJson
        );

        // 将可写数据源注册⾄transport模块的WritableDataSourceRegistry中
        // 这样收到控制台推送的规则时，Sentinel会先更新到内存，然后将规则写⼊到⽂件中
        WritableDataSourceRegistry.registerFlowDataSource(flowRuleWDS);
    }

    private <T> String encodeJson(T t) {
        return JSON.toJSONString(t);
    }

    private void mkdirsIfNotExist(String prefixPath) {
        File file = new File(prefixPath);
        if (!file.exists()) {
            file.mkdirs();
        }

    }

    private void createFileIfNotExist(String flowRulePath) throws IOException {
        File file = new File(flowRulePath);
        if (!file.exists()) {
            file.createNewFile();
        }

    }
}
